/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:hadss_adaptive_layout/hadss_adaptive_layout.dart';
import 'package:hadss_uni_input/hadss_uni_input.dart';
import 'package:provider/provider.dart';
import 'package:samples/utils/audio_player_manager.dart';
import 'package:samples/widget/float_play_card.dart';

import '../l10n/generated/app_localizations.dart';
import '../main.dart';
import '../widget/music_list_item.dart';
import '../widget/scroll_column.dart';

class MusicListPage extends StatefulWidget {
  const MusicListPage({Key? key}) : super(key: key);

  @override
  State<MusicListPage> createState() => _MusicListPageState();
}

class _MusicListPageState extends State<MusicListPage> {
  WidthBreakpoint screenType = WidthBreakpoint.xs;
  List<Map> listData = [];
  double _rotation = 0.0;
  final panDirection = PanDirection.all.value;
  double _offset = 0.0;
  final ScrollController _scrollController = ScrollController();
  double lastOffsetY = 0.0;

  //判断鼠标是否滚动一次
  bool scrollOnce = true;

  //是否为轻扫
  bool _swipeLightly = false;

  AudioPlayerManager audioPlayerManager = AudioPlayerManager();

  ScrollState _scrollState = ScrollState.idle;
  double _lastOffsetY = 0.0;
  double _scrollVelocity = 0.0;
  static const double _minSwipeVelocity = 800.0;
  static const double _minDragVelocity = 20.0;
  static const double _scrollSensitivity = 1.5;

  @override
  void initState() {
    super.initState();
    audioPlayerManager.init(listData, 0);
    WidgetsBinding.instance.addPostFrameCallback((_) {
      AppLocalizations il8n = AppLocalizations.of(context)!;
      configureListData(il8n);
      setState(() {});
    });
  }

  @override
  Widget build(BuildContext context) {
    return Consumer<RouteManager>(builder: (context, provider, child) {
      screenType = provider.widthBreakpoint;
      return _contentView(context);
    });
  }

  Widget _contentView(BuildContext context) {
    AppLocalizations il8n = AppLocalizations.of(context)!;
    return Scaffold(
      backgroundColor: const Color(0xffF1F3F5),
      appBar: AppBar(
        leading: IconButton(
          icon: Image.asset(
            "lib/assets/images/top_back.png",
            width: 40,
            height: 40,
          ),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
        title: Text(
          il8n.myCollect,
          style: const TextStyle(
              fontSize: 20, fontWeight: FontWeight.w600, color: Colors.black),
        ),
        shadowColor: Colors.transparent,
        backgroundColor: const Color(0xffF1F3F5),
      ),
      body: Stack(
        alignment: AlignmentDirectional.bottomEnd,
        children: [
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              LayoutBuilder(
                builder: (context, constraints) {
                  Size newSize = MediaQuery.of(context).size;
                  return OrientationBuilder(
                    builder: (context, orientation) {
                      return ScrollCloumnWidget(
                        screenType: screenType,
                      );
                    },
                  );
                },
              ),
              Padding(
                padding: const EdgeInsets.only(left: 15, right: 15),
                child: Row(
                  children: [
                    Image.asset(
                      "lib/assets/images/pause_icon.png",
                      width: 32,
                      height: 32,
                    ),
                    Padding(
                      padding: EdgeInsets.only(left: 10),
                      child: Text(
                        il8n.playAll,
                        style: const TextStyle(
                            fontSize: 18,
                            fontWeight: FontWeight.w700,
                            color: Color(0xE6000000)),
                      ),
                    ),
                  ],
                ),
              ),
              const SizedBox(
                height: 10,
              ),
              Expanded(
                child: ScrollConfiguration(
                  behavior: ScrollConfiguration.of(context).copyWith(
                    dragDevices: {
                      PointerDeviceKind.touch,
                      PointerDeviceKind.mouse,
                      PointerDeviceKind.trackpad,
                    },
                  ),
                  child: UnifiedGestureDetector(
                    pointerOptions: PointerOptions(
                      speed: 150,
                      direction: SwipeDirection.vertical,
                      enableSwipe: true,
                      enablePan: true,
                      panDirection: panDirection,
                    ),
                    onPanStart: onPanStart,
                    onPanUpdate: onPanUpdate,
                    onPanEnd: onPanEnd,
                    onPanCancel: onPanCancel,
                    onSwipe: onSwipe,
                    child: LayoutBuilder(
                      builder: (context, constraints) {
                        Size newSize = MediaQuery.of(context).size;
                        return OrientationBuilder(
                          builder: (context, orientation) {
                            return SingleChildScrollView(
                              controller: _scrollController,
                              child: GridRow(
                                gridCols: buildGridCols(),
                                columns: 32,
                                gutter: const Gutter(x: 15, y: 0),
                                margin: EdgeInsets.zero,
                                range: BreakpointRange(list: [
                                  320,
                                  600,
                                  840,
                                  1440,
                                  2000,
                                ]),
                              ),
                            );
                          },
                        );
                      },
                    ),
                  ),
                ),
              ),
              Container(
                height: 80,
              ),
            ],
          ),
          Positioned(
            left: 15,
            right: 15,
            bottom: 28,
            child: LayoutBuilder(
              builder: (context, constraints) {
                Size newSize = MediaQuery.of(context).size;
                return OrientationBuilder(
                  builder: (context, orientation) {
                    return FloatPlayCardWidget(
                      screenType: screenType,
                      listData: listData,
                    );
                  },
                );
              },
            ),
          ),
        ],
      ),
    );
  }

  List<GridCol> buildGridCols() {
    List<GridCol> items = [];
    for (var data in listData) {
      items.add(GridCol(
          span: SpanOption(
            xs: 32,
            sm: 32,
            md: 16,
            lg: 16,
            xl: 16,
            xxl: 16,
          ),
          offset: 0,
          order: listData.indexOf(data) + 1,
          child: MusicListItemWidget(
            data: data,
            screenType: screenType,
            itemClick: () {
              audioPlayerManager.setCurrentIndex(listData.indexOf(data));
              Navigator.pushNamed(
                context,
                '/musicDetail',
                arguments: {
                  "index": listData.indexOf(data),
                  "dataList": listData,
                  "isPlay": false,
                },
              );
            },
            itemDoubleClick: () {
              Navigator.pushNamed(
                context,
                '/musicDetail',
                arguments: {
                  "index": listData.indexOf(data),
                  "dataList": listData,
                  "isPlay": true,
                },
              );
            },
            menuClick: (value) {
              if (value is Map) {
                String type = value["type"] as String;
                if (type.isNotEmpty) {
                  if (type == "delete") {
                    listData.remove(data);
                  } else if (type == "collect") {
                    data["select"] = 1;
                  } else if (type == "unCollect") {
                    data["select"] = 0;
                  }
                  if (mounted) {
                    setState(() {});
                  }
                }
              }
            },
          )));
    }
    return items;
  }

  void configureListData(AppLocalizations il8n) {
    listData.clear();
    for (int a = 0; a < 100; a++) {
      Map data = {
        "title": "${il8n.music}$a",
        "id": a,
        "subtitle": "${il8n.singer}$a",
        "select": 0,
        "url": a == 0
            ? "lib/assets/audio.wav"
            : a % 2 == 0
                ? "lib/assets/audio.wav"
                : "lib/assets/audio2.m4a"
      };
      listData.add(data);
    }
  }

  void onSwipe(GestureEvent event) {
    if (event.angle == null || event.speed! < _minSwipeVelocity) {
      return;
    }

    _scrollState = ScrollState.swiping;
    _rotation = -event.angle!;
    
    // 计算惯性滚动的目标位置
    final double velocity = event.speed!;
    final double direction = _rotation < 0 ? -1.0 : 1.0;
    final double distance = velocity * 0.3; // 根据速度计算滚动距离
    final double targetOffset = (_scrollController.offset + (distance * direction))
        .clamp(0.0, _scrollController.position.maxScrollExtent);

    _scrollController.animateTo(
      targetOffset,
      duration: const Duration(milliseconds: 500),
      curve: Curves.easeOutCubic,
    ).then((_) {
      _scrollState = ScrollState.idle;
      _rotation = 0.0;
    });
  }

  void onPanStart(GestureEvent event) {
    _scrollState = ScrollState.dragging;
    _lastOffsetY = event.offsetY ?? 0.0;
  }

  void onPanUpdate(GestureEvent event) {
    if (event.offsetY == null) return;

    if (_scrollState != ScrollState.dragging) return;

    final double deltaY = event.offsetY! - _lastOffsetY;
    _scrollVelocity = event.velocityY ?? 0.0;

    if (_scrollVelocity.abs() > _minDragVelocity) {
      final double newOffset = _scrollController.offset - (deltaY * _scrollSensitivity);
      _scrollController.jumpTo(newOffset.clamp(
        0.0,
        _scrollController.position.maxScrollExtent,
      ));
    }

    _lastOffsetY = event.offsetY!;
  }

  void onPanEnd(GestureEvent event) {
    if (_scrollState == ScrollState.dragging) {
      final double velocity = event.velocityY ?? 0.0;
      
      if (velocity.abs() > _minSwipeVelocity) {
        _rotation = velocity;
        // 触发轻扫效果
        onSwipe(GestureEvent(
          offsetX: 0,
          offsetY: velocity,
          velocityX: 0,
          velocityY: velocity,
          speed: velocity.abs(),
          angle: velocity > 0 ? 90.0 : -90.0,
        ));
      }
    }
    
    _scrollState = ScrollState.idle;
  }

  void onPanCancel(GestureEvent event) {
    _scrollState = ScrollState.idle;
  }
}

// 滑动状态枚举
enum ScrollState {
  idle,
  dragging,
  swiping
}
